<?php
namespace Tbf\Component\Encode;
/**
 * 各种编码
 * 出现错误抛出Tbf\Error\EncodeException异常
 * */
class EncodeUtil
{
    /**
     * 转移html
     * */
    public static function htmlSpecialChars($string)
    {
        return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, 'utf-8');
    }
    /**
     * 用json和gzdeflate打包和压缩数据
     * */
    public static function jsonGzEncode($data)
    {
        $data = self::jsonEncode($data);
        $data = self::gzdeflate($data);

        return $data;
    }
    /**
     * 用gzinflate和json解压和还原数据
     * */
    public static function jsonGzDecode($data)
    {
        $data = self::gzinflate($data);
        $data = self::jsonDecode($data);

        return $data;
    }
    public static function gzdeflate($input)
    {
        if (!is_string($input)) {
            throw new EncodeException('gzdeflate fail! input not string');
        }
        $output = gzdeflate($input);
        if ($output===false) {
            throw new EncodeException('gzdeflate fail! return false');
        }

        return $output;
    }
    public static function gzinflate($input)
    {
        if (!is_string($input)) {
            throw new EncodeException('gzinflate fail! input not string');
        }
        $output = gzinflate($input);
        if ($output===false) {
            throw new EncodeException('gzinflate fail! return false');
        }

        return $output;
    }
    /**
     * 封装json_encode错误处理
     * */
    public static function jsonEncode($data)
    {
        $ret = json_encode($data);
        if ($ret===false) {
            $error_code = json_last_error();
            $error_string = self::jsonErrorCodeToString($error_code);
            throw new EncodeException('encode json fail! json_last_error():'.$error_string);
        }

        return $ret;
    }
    /**
     * 封装json_decode错误处理
     * */
    public static function jsonDecode($data)
    {
        $ret = json_decode($data,true);
        $error_code = json_last_error();
        if ($error_code!==JSON_ERROR_NONE) {
            $error_string = self::jsonErrorCodeToString($error_code);
            throw new EncodeException('decode json fail! json_last_error():'.$error_string);
        }

        return $ret;
    }
    private function jsonErrorCodeToString($code)
    {
        switch ($code) {
        case JSON_ERROR_NONE:
            return 'No errors';
            break;
        case JSON_ERROR_DEPTH:
            return 'Maximum stack depth exceeded';
            break;
        case JSON_ERROR_STATE_MISMATCH:
            return 'Underflow or the modes mismatch';
            break;
        case JSON_ERROR_CTRL_CHAR:
            return  'Unexpected control character found';
            break;
        case JSON_ERROR_SYNTAX:
            return  'Syntax error, malformed JSON';
            break;
        case JSON_ERROR_UTF8:
            return 'Malformed UTF-8 characters, possibly incorrectly encoded';
            break;
        default:
            return 'Unknown error';
            break;
        }
    }
    /**
     * 16进制字符串转二进制-工具函数
     * */
    public static function hex2bin($hex)
    {
        return pack('H*',$hex);
    }
    /**
     * 可以阅读的字符串
     * 不好用,汉字不见了...
     * 编码ascii,把所有不能阅读的字符串全部转为 \x8f 之类的东西
     * \n和\r不做处理
     * 来自python27源码:PyString_Repr函数(文件:./Objects/stringobject.c)
     * */
    public static function readableAscii($str)
    {
        $length = strlen($str);
        $output = '';
        for ($i=0;$i<$length;$i++) {
            $chr = $str[$i];
            $chr_ord = ord($str[$i]);
            if ($chr=="\n"||$chr=="\r") {
                $output.=$chr;
            } elseif ($chr_ord<0x20 || $chr_ord>=0x7f) {
                $output.=sprintf('\\x%02x',$chr_ord);
            } else {
                $output.=$chr;
            }
        }

        return $output;
    }

}
